package com.ihrm.system.controller;


import com.ihrm.common.controller.BaseController;
import com.ihrm.common.entity.PageResult;
import com.ihrm.common.entity.Result;
import com.ihrm.common.entity.ResultCode;
import com.ihrm.common.exception.CommonException;
import com.ihrm.common.poi.ExcelImportUtil;
import com.ihrm.common.utils.JwtUtils;
import com.ihrm.common.utils.PermissionConstants;
import com.ihrm.domain.system.Permission;
import com.ihrm.domain.system.Role;
import com.ihrm.domain.system.User;
import com.ihrm.domain.system.response.ProfileResult;
import com.ihrm.domain.system.response.UserSimpleResult;
import com.ihrm.system.client.DepartmentFeignClient;
import com.ihrm.system.service.PermissionService;
import com.ihrm.system.service.UserService;
import io.jsonwebtoken.Claims;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 解决跨域
 */
@CrossOrigin
/**
 * 声明restController
 */
@RestController
/**
 * 设置父路径
 */
@RequestMapping(value = "/sys")
public class UserController extends BaseController {
    @Autowired
    private UserService userService;
    
    @Autowired
    private PermissionService permissionService;
    
    @Autowired
    private JwtUtils jwtUtils;
    
    @Autowired
    private DepartmentFeignClient departmentFeignClient;
    
    
    
    @RequestMapping("/user/upload/{id}")
    public Result upload(@PathVariable String id,@RequestParam(name = "file") MultipartFile file) throws IOException{
        /**
         * 调用service保存图片(获取到图片的访问地址(dataUrl | http))
         */
        String imgUrl = userService.uploadImage(id, file);
    
        /**
         * 返回数据
         */
        return new Result(ResultCode.SUCCESS,imgUrl);
    }
    
    
    /**
     * 导入Excel,添加用户
     * 文件上传:springboot
     */
    @RequestMapping(value = "/user/import",method = RequestMethod.POST)
    public Result importUser(@RequestParam(name = "file")MultipartFile file) throws Exception{
//        /**
//         * 解析Excel
//         * 1.1.根据Excel文件创建工作簿
//         */
//        Workbook wb = new XSSFWorkbook(file.getInputStream());
//        /**
//         * 1.2.获取Sheet
//         */
//        Sheet sheet = wb.getSheetAt(0);
//        /**
//         * 1.3.获取Sheet中的每一行，和每一个单元格
//         * 2.获取用户数据
//         */
//        List<User> list=new ArrayList<>();
//        for(int rowNum=1;rowNum<=sheet.getLastRowNum();rowNum++){
//            Row row = sheet.getRow(rowNum);
//            Object[] values = new Object[row.getLastCellNum()];
//            for(int cellNum=1;cellNum<row.getLastCellNum();cellNum++){
//                Cell cell = row.getCell(cellNum);
//                Object value=getCellValue(cell);
//                values[cellNum]=value;
//            }
//            User user=new User(values);
//            list.add(user);
//        }
    
        /**
         * 解析Excel
         */
        List<User> list = new ExcelImportUtil(User.class).readExcel(file.getInputStream(), 1, 1);
    
        /**
         * 批量保存用户
         */
        userService.saveAll(list,companyId,companyName);
        
        return new Result(ResultCode.SUCCESS);
    }
    
    public static Object getCellValue(Cell cell){
        /**
         * 获取到单元格的属性类型
         */
        CellType cellType = cell.getCellType();
        /**
         * 根据单元格数据类型获取数据
         */
        Object value=null;
        switch (cellType){
            case STRING:
                value=cell.getStringCellValue();
                break;
            case BOOLEAN:
                value=cell.getBooleanCellValue();
                break;
            case NUMERIC:
                if(DateUtil.isCellDateFormatted(cell)){
                    /**
                     * 日期格式
                     */
                    value=cell.getDateCellValue();
                }else {
                    /**
                     * 数字
                     */
                    value=cell.getNumericCellValue();
                }
                break;
            case FORMULA:
                /**
                 * 公式
                 */
                value=cell.getCellFormula();
                break;
            default:
                break;
        }
        return value;
    }
    
    /**
     * 测试Feign组件
     * 调用系统微服务的/test接口传递部门id，通过feign调用部门微服务获取部门信息
     */
    @RequestMapping(value = "/test/{id}", method = RequestMethod.GET)
    public Result testFeign(@PathVariable(value = "id") String id) {
        Result result = departmentFeignClient.findById(id);
        return result;
    }
    
    
    /**
     * 分配角色
     */
    @RequestMapping(value = "/user/assignRoles",method = RequestMethod.PUT)
    public Result assignRoles(@RequestBody Map<String,Object> map){
        /**
         * 获取被分配的用户id
         */
        String userId = (String) map.get("id");
        /**
         * 获取到角色的id列表
         */
        List<String> roleIds = (List<String>) map.get("roleIds");
        /**
         * 调用service完成角色分配
         */
        userService.assignRoles(userId,roleIds);
        return Result.SUCCESS();
    }
    
    
    /**
     * 保存
     */
    @RequestMapping(value = "/user",method = RequestMethod.POST)
    public Result assignRoles(@RequestBody User user){
        /**
         * 设置保存企业id
         */
        user.setCompanyId(companyId);
        user.setCompanyName(companyName);
        /**
         * 保存用户
         */
        userService.save(user);
        /**
         * 构造返回结果
         */
        return new Result(ResultCode.SUCCESS);
    }
    /**
     * 查询企业的部门列表
     * 指定企业id
     */
    @RequestMapping(value = "/user",method = RequestMethod.GET)
    public Result findAll(int page,int size,@RequestBody Map map){
        /**
         * 设置当前企业id
         */
        map.put("companyId",companyId);
        /**
         * 完成查询
         */
        Page<User> pageUser=userService.findAll(map,page,size);
        /**
         * 构造返回结果
         */
        PageResult pageResult = new PageResult(pageUser.getTotalElements(), pageUser.getContent());
        return new Result(ResultCode.SUCCESS,pageResult);
    }
    /**
     * 根据id查询User
     */
    @RequestMapping(value = "/user/{id}",method = RequestMethod.GET)
    public Result findById(@PathVariable(value = "id") String id){
        User user = userService.findById(id);
        return new Result(ResultCode.SUCCESS,user);
    }
    
    /**
     * 修改User
     */
    @RequestMapping(value = "/user/{id}",method = RequestMethod.PUT)
    public Result update(@PathVariable(value = "id") String id,@RequestBody User user){
        user.setId(id);
        userService.update(user);
        return new Result(ResultCode.SUCCESS);
    }
    
    /**
     * 根据id删除
     */
    @RequiresPermissions(value="API-USER-DELETE")
    @RequestMapping(value = "/user/{id}",method = RequestMethod.DELETE,name = "API-USER-DELETE")
    public Result delete(@PathVariable(value = "id") String id){
        userService.deleteById(id);
        return new Result(ResultCode.SUCCESS);
    }
    
    @RequestMapping(value = "/user/simple",method = RequestMethod.GET)
    public Result simple() throws Exception{
        List<UserSimpleResult> list=new ArrayList<>();
        List<User> users=userService.findAll(companyId);
        for (User user:users){
            list.add(new UserSimpleResult(user.getId(),user.getUsername()));
        }
        return new Result(ResultCode.SUCCESS,list);
    }
    
    
    /**
     * 用户登录：
     *  1.通过service根据mobile查询用户
     *  2.比较password
     *  3.生成jwt信息
     */
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public Result login(@RequestBody Map<String,String> loginMap){
        String mobile = loginMap.get("mobile");
        String password = loginMap.get("password");
        try{
            /**
             * 1.构造登录令牌 UsernamePasswordToken
             * 加密密码
             */
            password = new Md5Hash(password, mobile, 3).toString();//密码，盐，加密次数
            System.out.println("加密后的密码"+password);
            UsernamePasswordToken upToken = new UsernamePasswordToken(mobile, password);
            /**
             * 2.获取subject
             */
            Subject subject = SecurityUtils.getSubject();
            /**
             * 3.调用login方法，进入Realm完成认证
             */
            subject.login(upToken);
            /**
             * 4.获取sessionId
             */
            String sessionId = (String) subject.getSession().getId();
            /**
             * 构造返回结果
             */
            System.out.println("sessionId"+sessionId);
            return new Result(ResultCode.SUCCESS,sessionId);
        }catch (Exception e){
            return new Result(ResultCode.MOBILEORPASSWORDERROR);
        }

    }
    
    /**
     * 用户登录成功之后，获取用户信息
     *  1.获取用户id
     *  2.根据用户id查询用户
     *  3.构建返回值对象
     *  4.响应
     */
    @RequestMapping(value = "/profile",method = RequestMethod.POST)
    public Result profile(HttpServletRequest request) throws Exception{
    
        /**
         * 获取session中的安全数据
         */
        Subject subject = SecurityUtils.getSubject();
        /**
         * 1.获取所有的安全数据集合
         */
        PrincipalCollection principals = subject.getPrincipals();
        /**
         * 2.获取安全数据
         */
        ProfileResult result = (ProfileResult) principals.getPrimaryPrincipal();
        
        return new Result(ResultCode.SUCCESS,result);
    }
}
